package com.jeeplus.modules.web.im;

import com.jeeplus.common.utils.SpringContextHolder;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.modules.web.entity.YjCommand;
import com.jeeplus.modules.web.mapper.WxOrderMapper;
import com.jeeplus.modules.web.mapper.YjCommandMapper;
import com.jeeplus.modules.web.mapper.YjEquipmentMapper;
import org.apache.log4j.Logger;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;

/**
 * 写消息线程
 *
 * @author way
 *
 */
public class OutputThread extends Thread {
	private static Logger log = Logger.getLogger(OutputThread.class);

	// //获取dao 接口 防止注入失败
	private YjCommandMapper yjCommandMapper = SpringContextHolder.getBean(YjCommandMapper.class); // 获取dao
																									// 接口
																									// 防止注入失败
	private WxOrderMapper wxOrderMapper = SpringContextHolder.getBean(WxOrderMapper.class); // 获取dao 接口
																							// 防止注入失败
	private YjEquipmentMapper yjEquipmentMapper = SpringContextHolder.getBean(YjEquipmentMapper.class);
	private volatile int version;
	private String mac;
	private DataOutputStream oos;
	boolean isStart = true;// 循环标志位

	private Socket socket;

	public OutputThread(Socket socket) {
		try {
			this.socket = socket;
			oos = new DataOutputStream(socket.getOutputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void setStart(boolean isStart) {// 用于外部关闭写线程
		this.isStart = isStart;
	}

	public String getMac() {
		return mac;
	}

	public void setMac(String mac) {
		this.mac = mac;
	}

	public void setVersion(int version) {
		this.version = version;
	}

	@Override
	public void run() {
		int i = 0;
		try {
			while (isStart) {
				if(version!=0){
					OutputStream outputStream = oos;


					if (mac == null) {
						Thread.sleep(3000);
						outputStream.write(EquipmentCommand.WAIT);
						continue;
					}

					Integer is = wxOrderMapper.getVersion(mac);
					is = is == null ? 0 : is;
					if (is != version) {
						System.out.println("已丢失");
						setStart(false);
						outputStream.write(EquipmentCommand.OUT);
						break;
					}

					/*
					 * 下发心跳包，维持链接
					 */
					if (StringUtils.isNotEmpty(this.mac)) {
						YjCommand entity = yjCommandMapper.getType("0", this.mac);
						if (entity == null) {
							// byte buffer[]=decode("AA550F00030343C1");
							// printHexString(buffer);
							if (i == 30) {
								i = 0;
								outputStream.write(EquipmentCommand.HEARTBEAT);
							} else {
								++i;
							}

						} else {// 设备在线
							outputStream.write(entity.getText().getBytes());
						}

						// 无用户则阻塞线程
						// synchronized (this) {
						//// wait();
						// }
					}

					// 给硬件发指令-->硬件处理-->回发回调信息-->回调信息处理-->标记命令结束，
					// 如果发送过快，这一套流程耗时将超过一秒，导致重复发送，硬件方将重复发送关机回调，由于网络问题，甚至可能导致多条关机回调信息粘连，故将延时设大
					// 后续版本与硬件协调，只接受一条，其他的都不处理，保证幂等性
					Thread.sleep(2000);
				}
			}

			if (oos != null)// 循环结束后，关闭流，释放资源
				oos.close();
			if (socket != null)
				socket.close();
		} catch (SocketException e) {
			try {
				// addEerror("2",wxEquipment.getEquipment(this.mac.replace("\n","").trim()),"oLx32v01UGFhzD1MiZ2avMrrVgyA",this.mac.replace("\n","").trim());
				// addEerror("2",wxEquipment.getEquipment(this.mac.replace("\n","").trim()),"oLx32v7Siz0B3fo8z5j6sGi5Dwrw",this.mac.replace("\n","").trim());
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			log.error(e);
			log.debug(mac + ":断开了");
			if (oos != null)
				try {
					oos.close();
					if (socket != null)
						socket.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			e.printStackTrace();
		} catch (Exception e) {
			log.error(e);
			log.debug(mac + ":断开了");
			e.printStackTrace();
		}
	}

	private static String hexString = "0123456789ABCDEF"; // 此处不可随意改动

	/* 将16进制数字解码成字符串 */
	public static byte[] decode(String bytes) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream(bytes.length() / 2);
		// 将每2位16进制整数组装成一个字节
		for (int i = 0; i < bytes.length(); i += 2)
			baos.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString.indexOf(bytes.charAt(i + 1))));
		return baos.toByteArray();
	}

	public static void printHexString(byte[] b) {
		String str = "";
		for (int i = 0; i < b.length; i++) {
			String hex = Integer.toHexString(b[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			str += hex;
		}
		System.out.println(str);
	}
}